home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume90 / unix / ls_3_1 / part02 < prev    next >
Encoding:
Internet Message Format  |  1990-04-10  |  36.4 KB

  1. Path: xanth!cs.odu.edu!Amiga-Request
  2. From: Amiga-Request@cs.odu.edu (Amiga Sources/Binaries Moderator)
  3. Newsgroups: comp.sources.amiga
  4. Subject: v90i132: ls 3.1 - UNIX-like ls utility, Part02/03
  5. Message-ID: <12129@xanth.cs.odu.edu>
  6. Date: 10 Apr 90 21:25:55 GMT
  7. Sender: tadguy@cs.odu.edu
  8. Reply-To: kim@uts.amdahl.com (Kim E. DeVaughn)
  9. Lines: 1388
  10. Approved: tadguy@cs.odu.edu (Tad Guy)
  11. X-Mail-Submissions-To: Amiga@cs.odu.edu
  12. X-Post-Discussions-To: comp.sys.amiga
  13.  
  14. Submitted-by: kim@uts.amdahl.com (Kim E. DeVaughn)
  15. Posting-number: Volume 90, Issue 132
  16. Archive-name: unix/ls-3.1/part02
  17.  
  18. #!/bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 2 (of 3)."
  25. # Contents:  src/lssup.a
  26. # Wrapped by tadguy@xanth on Tue Apr 10 17:22:48 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'src/lssup.a' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'src/lssup.a'\"
  30. else
  31. echo shar: Extracting \"'src/lssup.a'\" \(33907 characters\)
  32. sed "s/^X//" >'src/lssup.a' <<'END_OF_FILE'
  33. X* --------------------------------------------------------------------- *
  34. X* LSSUP.A - Assembly support routines for ls.c
  35. X* Written by Justin V. McCormick 89-07-24
  36. X* --------------------------------------------------------------------- *
  37. X    IFD    CAPE
  38. X    CSYMFMT
  39. X    BASEREG    B
  40. X    SMALLOBJ
  41. X    ADDSYM
  42. X    OPTIMON
  43. X    IDNT    "lssup.a"
  44. X    ENDC
  45. X
  46. X
  47. XSYS    MACRO    *
  48. X    IFGT    NARG-2
  49. X    FAIL    !!!
  50. X    ENDC
  51. X    IFEQ    NARG-2
  52. X    MOVE.L    \2,a6
  53. X    ENDC
  54. X    JSR    LVO\1(a6)
  55. X    ENDM
  56. X
  57. XXLVO    MACRO    *
  58. X    XREF    LVO\1
  59. X    ENDM
  60. X
  61. X; Equates
  62. Xfib_DirEntryType EQU    $4 
  63. Xfib_FileName    EQU    $8
  64. Xfib_Size    EQU    $7C
  65. Xfib_NumBlocks    EQU    $80
  66. Xfib_DateStamp    EQU    $84
  67. Xfib_SIZEOF    EQU    $104 
  68. X
  69. Xds_Days        EQU    $0
  70. Xds_Minute    EQU    $4
  71. Xds_Tick        EQU    $8
  72. X
  73. XLH_HEAD        EQU    $0
  74. XLN_PRED        EQU    $4
  75. XLN_SUCC        EQU    $0
  76. X
  77. Xfe_Node    equ    0
  78. Xfe_Fib    equ    8
  79. Xpr_ConsoleTask        EQU    $A4
  80. X
  81. XMEMF_CLEAR        EQU    $10000
  82. Xsp_Msg            EQU    $0
  83. Xsp_Pkt            EQU    $14
  84. Xsp_SIZEOF        EQU    $44
  85. Xdp_Link            EQU    $0
  86. Xdp_Port            EQU    $4
  87. Xdp_Arg1            EQU    $14
  88. Xdp_Type            EQU    $8
  89. XACTION_SCREEN_MODE    EQU    $3E2
  90. XLN_NAME            EQU    $A
  91. XLN_PRI            EQU    $9
  92. XLN_TYPE            EQU    $8
  93. XMP_FLAGS        EQU    $E
  94. XMP_MSGLIST        EQU    $14
  95. XMP_SIGBIT        EQU    $F
  96. XMP_SIGTASK        EQU    $10
  97. XMP_SIZE            EQU    $22
  98. XNT_MSGPORT        EQU    $4
  99. XPA_SIGNAL        EQU    $0
  100. X
  101. X* Library offsets
  102. X    XLVO    AddPort
  103. X    XLVO    AddTail
  104. X    XLVO    AllocMem
  105. X    XLVO    AllocSignal
  106. X    XLVO    CopyMem
  107. X    XLVO    Debug
  108. X    XLVO    Examine
  109. X    XLVO    FindTask
  110. X    XLVO    FreeMem
  111. X    XLVO    FreeSignal
  112. X    XLVO    GetMsg
  113. X    XLVO    Input
  114. X    XLVO    Insert
  115. X    XLVO    IoErr
  116. X    XLVO    IsInteractive
  117. X    XLVO    Output
  118. X    XLVO    ParentDir
  119. X    XLVO    PutMsg
  120. X    XLVO    RawDoFmt
  121. X    XLVO    Read
  122. X    XLVO    RemPort
  123. X    XLVO    WaitForChar
  124. X    XLVO    WaitPort
  125. X    XLVO    Write
  126. X    XLVO    UnLock
  127. X
  128. X* External constants
  129. X    XREF    @AllocFib
  130. X    XREF    @CleanUp
  131. X    XREF    @stpcpy
  132. X    XREF    @strcat
  133. X    XREF    @strlen
  134. X    XREF    baddatestr
  135. X    XREF    badtimestr
  136. X    XREF    ColonStr
  137. X    XREF    datepat
  138. X    XREF    dayspermonth
  139. X    XREF    DOSBase
  140. X    XREF    gwbrstr
  141. X    XREF    LSFlags
  142. X    XREF    NoFindFmtStr
  143. X    XREF    NoRAMMsg
  144. X    XREF    RamNameStr
  145. X    XREF    SlashStr
  146. X    XREF    sortkey
  147. X    XREF    timepat
  148. X
  149. X    SECTION    CODE
  150. X* --------------------------------------------------------------------- *
  151. X* VOID *myalloc (LONG)
  152. X*   d0            d0
  153. X* --------------------------------------------------------------------- *
  154. X    XDEF    @myalloc
  155. X@myalloc:
  156. X    movem.l    d2/a6,-(sp)
  157. X    addq.l    #4,d0            ;Include sizeof(LONG)
  158. X    move.l    d0,d2            ;Copy to survive AllocMem
  159. X    moveq    #0,d1            ;MEMF_ANYTHING
  160. X    SYS    AllocMem,4        ;AllocMem(size + 4, 0L)
  161. X    tst.l    d0            ;Got it?
  162. X     beq.s    1$
  163. X    movea.l    d0,a6            ;Copy pointer
  164. X    move.l    d2,(a6)+        ;Stash size in first 4 bytes
  165. X    move.l    a6,d0            ;return final pointer in d0
  166. X1$
  167. X    movem.l    (sp)+,d2/a6
  168. X    rts
  169. X
  170. X* --------------------------------------------------------------------- *
  171. X* VOID myfree (VOID *)
  172. X*               a0
  173. X* --------------------------------------------------------------------- *
  174. X    XDEF    @myfree
  175. X@myfree:
  176. X    move.l    a6,-(sp)
  177. X
  178. X    lea    -4(a0),a1        ;Put in sys reg
  179. X    move.l    (a1),d0            ;d0 = size to free
  180. X    SYS    FreeMem,4
  181. X
  182. X    movea.l    (sp)+,a6
  183. X    rts
  184. X
  185. X* --------------------------------------------------------------------- *
  186. X* void asprintf(wstr, formatstring, args)
  187. X*   char *wstr;
  188. X*   char *formatstring;
  189. X*   char **args;
  190. X* 
  191. X* Synopsis: Given formatstring and args to format, formats output to wstr.
  192. X* Similar to sprintf(), except doesn't handle floats.
  193. X* --------------------------------------------------------------------- *
  194. X    XDEF    asprintf
  195. Xasprintf:
  196. X    link    a5,#0
  197. X    movem.l    d0-d2/a0-a3/a6,-(sp)    ;Save everything we might clobber
  198. X
  199. X* Call format function to convert fmtstring and args to buffer on the stack
  200. X    movea.l    12(a5),a0        ;Grab format string
  201. X    lea    16(a5),a1        ;Grab EA of arguments
  202. X    lea    kput1,a2        ;Grab EA of output subroutine
  203. X    movea.l    8(a5),a3        ;Grab EA of dest workspace
  204. X    SYS    RawDoFmt,4        ;Format it into workspace
  205. X
  206. X    movem.l    (sp)+,d0-d2/a0-a3/a6    ;Restore registers
  207. X    unlk    a5            ;And stack frame
  208. X    rts
  209. X
  210. X* --------------------------------------------------------------------- *
  211. X* RawDoFmt() output routine for xprintf, called for each formatted char.
  212. X* Takes byte in d0 and puts in buffer pointed to by a3, then increments a3.
  213. X* --------------------------------------------------------------------- *
  214. X    XDEF    kput1
  215. Xkput1:
  216. X    move.b    d0,(a3)+
  217. X    rts
  218. X
  219. X* --------------------------------------------------------------------- *
  220. X* void GetWinBounds(width, height)
  221. X*   long *width, *height;
  222. X*          a0       a1
  223. X* Find current console window, determine width and height
  224. X* in terms of current font, update width and height VPARMS passed.
  225. X* --------------------------------------------------------------------- *
  226. Xheight    EQU    -4
  227. Xwidth    EQU    -8
  228. Xconid    EQU    -12
  229. Xpacket    EQU    -16
  230. Xrpport    EQU    -20
  231. Xrpstr    EQU    -40
  232. X
  233. X    XDEF    @GetWinBounds
  234. X@GetWinBounds:
  235. X    link    a5,#-44
  236. X    movem.l    d2-d4/a2/a6,-(sp)
  237. X
  238. X    move.l    a0,width(a5)        ;Save width/height pointers on stack
  239. X    move.l    a1,height(a5)
  240. X
  241. X    SYS    Input,DOSBase(a4)    ;Grab Input filehandle
  242. X    move.l    d0,d1
  243. X    SYS    IsInteractive        ;IsInteractive(Input())?
  244. X    tst.l    d0
  245. X     beq.s    gwbnowbrep        ;Nope, can't get a bounds report
  246. X    SYS    Output
  247. X    move.l    d0,d1
  248. X    SYS    IsInteractive        ;IsInteractive(Output())?
  249. X    tst.l    d0
  250. X     beq.s    gwbnowbrep        ;Nope, don't clutter output stream
  251. X
  252. X    suba.l    a1,a1
  253. X    SYS    FindTask,4        ;d0 = FindTask(0L), our process
  254. X    movea.l    d0,a0            ;Transfer to address reg
  255. X    move.l    pr_ConsoleTask(a0),conid(a5) ;Save proc->pr_ConsoleTask
  256. X    tst.l    conid(a5)        ;Is there really a console there?
  257. X     bne.s    gwbgotcon        ;Yep
  258. X
  259. Xgwbnowbrep:
  260. X* Else we cannot get a window bounds report from this source
  261. X    moveq    #23,d1            ;return H=23
  262. X    moveq    #77,d2            ;       W=77
  263. X    bra    gwbupdate
  264. X
  265. Xgwbgotcon:
  266. X    moveq    #0,d4            ;Clear our success status register
  267. X
  268. X    moveq    #0,d0
  269. X    movea.l    d0,a0
  270. X    jsr    CreatePort
  271. X    move.l    d0,rpport(a5)        ;rpport = CreatePort(0L, 0L)
  272. X     beq    gwbdone            ;Oops, no signals or ram available!
  273. X    moveq    #sp_SIZEOF,d0
  274. X    jsr    @myalloc
  275. X    move.l    d0,packet(a5)        ;packet = AllocBlock(sizeof(*packet))
  276. X     beq    gwbfreeport        ;Oops, no ram, free up port
  277. X
  278. X* Okay, we got our process id, reply port, and packet
  279. X* Now toggle the console into raw mode
  280. X    movea.l    rpport(a5),a2
  281. X    movea.l    d0,a1
  282. X    movea.l    conid(a5),a0
  283. X    moveq    #1,d0
  284. X    jsr    SetConsoleType        ;SetConsoleType(1L, conid, packet, rpport)
  285. X
  286. X* Request a window bounds report
  287. X    SYS    Output,DOSBase(a4)
  288. X    move.l    d0,d1
  289. X    moveq    #4,d3
  290. X    lea    gwbrstr(a4),a0
  291. X    move.l    a0,d2
  292. X    SYS    Write,DOSBase(a4)    ;Write(Output(), "\2330 q", 4L);
  293. X    cmpi.l    #$0004,d0        ;Did the console choke on it?
  294. X     bne    gwbsetcook        ;hmmm, see if we can back out gracefully
  295. X
  296. X* Read the report string into stack buffer, if there is one
  297. X    move.l    #10000,d2
  298. X    SYS    Input
  299. X    move.l    d0,d1
  300. X    SYS    WaitForChar        ;WaitForChar(Input(), 10000L) (.01 secs)
  301. X    tst.l    d0            ;Did we get the report?
  302. X     beq    gwbsetcook        ;Nope, must not be a report coming
  303. X    
  304. X    SYS    Input
  305. X    move.l    d0,d1
  306. X    moveq    #16,d3            ;Don't let it get longer than 16 characters
  307. X    lea    rpstr(a5),a0        ;Point to input string area
  308. X    move.l    a0,d2
  309. X    SYS    Read            ;Read(Input(), rpstr, 16L)
  310. X    move.l    d0,d4            ;Save read length while we close shop
  311. X
  312. X* Turn the console back to cooked mode pronto to avoid cursor blink
  313. Xgwbsetcook:
  314. X    movea.l    rpport(a5),a2
  315. X    movea.l    packet(a5),a1
  316. X    movea.l    conid(a5),a0
  317. X    moveq    #0,d0
  318. X    jsr    SetConsoleType        ;SetConsoleType(0L, conid, packet, rpport)
  319. X
  320. X* Release resources we borrowed
  321. Xgwbfreepack:
  322. X    move.l    packet(a5),d0        ;Did we allocate a packet?
  323. X     beq.s    gwbfreeport        ;nay, check for port to free
  324. X    movea.l    d0,a0
  325. X    jsr    @myfree            ;Else FreeBlock(packet)
  326. X
  327. Xgwbfreeport:
  328. X    move.l    rpport(a5),d0        ;if (rpport)...
  329. X     beq    gwbdone            ;nope
  330. X    jsr    DeletePort        ;Else DeletePort(rpport)
  331. X
  332. X* Finally, sanity check window bounds report string
  333. X* d4 = length of report string according to Read()
  334. X    cmpi.l    #9,d4            ;Less than 8 characters returned?
  335. X     ble    gwbdone            ;hmmm, phonky bounds report from DOS?
  336. X    lea    rpstr(a5),a2        ;a2 = rpstr
  337. X    cmpi.b    #';',4(a2)        ;Matches a typical report template?
  338. X     bne    gwbdone            ;nope, got some weird junk back?
  339. X    cmpi.b    #'r',-1(a2,d4.w)    ;Last byte is 'r' for report?
  340. X     bne    gwbdone            ;Nope, message fubar!
  341. X
  342. X* Parse the height and width variables from the field now
  343. X* Our report format looks like this in hex:
  344. X*     9b 31 3b 31 3b y2 y1 3b x2 x1 20 72
  345. X* Or in ascii:
  346. X*    <0x9b>1;1;20;77 r
  347. X* Which would indicate a width of 77 cols and a height of 20 rows for
  348. X* the current console device
  349. X*
  350. X* REGS:    a2 points to beginning of 'r' terminated string
  351. X
  352. X    addq.w    #5,a2            ;Point to first char of Y size
  353. X    moveq    #0,d1            ;Clear out work reg
  354. X
  355. X* Convert ascii rows value to LONG, update host data
  356. X    move.b    (a2)+,d1        ;Grab a Y
  357. X    subi.w    #'0',d1            ;Less ascii offset
  358. X    cmpi.b    #';',(a2)        ;Any more Y digits?
  359. X     beq.s    1$            ;Nope
  360. X    mulu    #10,d1            ;Else shift by 10
  361. X    add.b    (a2)+,d1        ;Add least significant Y digit
  362. X    subi.b    #'0',d1            ;Less ascii offset
  363. X    cmpi.b    #';',(a2)        ;Any more Y digits?
  364. X     beq.s    1$            ;Nope
  365. X    mulu    #$000a,d1        ;Else shift by 10
  366. X    add.b    (a2)+,d1        ;Add least significant Y digit
  367. X    subi.b    #'0',d1            ;Less ascii offset
  368. X                    ;We'll assume screen height < 999 rows    
  369. X1$
  370. X* Convert ascii columns value to LONG, update host data
  371. X    addq.w    #1,a2            ;Move past the ';' separator
  372. X    moveq    #0,d2            ;Zap work reg
  373. X    move.b    (a2)+,d2        ;Grab msd of X
  374. X    cmpi.b    #' ',d2            ;Premature end?
  375. X     beq    gwbdone            ;Huh, must be garbage - don't update VPARMS
  376. X    cmpi.b    #';',d2            ;Also a possible error
  377. X     beq    gwbdone
  378. X    cmpi.b    #'r',d2            ;And what about this?
  379. X     beq    gwbdone
  380. X
  381. X    subi.b    #'0',d2            ;Okay, adjust ascii offset
  382. X    cmpi.b    #' ',(a2)        ;Hit end of report?
  383. X     beq.s    2$            ;Yep
  384. X    mulu    #$000a,d2        ;Else shift by 10
  385. X    add.b    (a2)+,d2        ;Add next digit
  386. X    subi.b    #'0',d2            ;Ascii adjust
  387. X    cmpi.b    #' ',(a2)        ;Hit end of report?
  388. X     beq.s    2$            ;Yep
  389. X    mulu    #$000a,d2        ;Else shift by 10
  390. X    add.b    (a2),d2            ;Add next digit
  391. X    subi.b    #'0',d2            ;Ascii adjust
  392. X
  393. X2$
  394. Xgwbupdate:
  395. X* Finally, update parameters by reference
  396. X    movea.l    height(a5),a0        ;Grab height VPARM
  397. X    move.l    d1,(a0)            ;*height = d1
  398. X    movea.l    width(a5),a0        ;Grab width VPARM
  399. X    move.l    d2,(a0)            ;*width = d2
  400. X
  401. Xgwbdone:
  402. X    movem.l    (sp)+,d2-d4/a2/a6
  403. X    unlk    a5
  404. X    rts
  405. X
  406. X* --------------------------------------------------------------------- *
  407. X* void __asm SetConsoleType(flag, id, packet, port)
  408. X*   register __d0 long flag;
  409. X*   register __a0 struct Process *id;
  410. X*   register __a1 struct StandardPacket *packet;
  411. X*   register __a2 struct MsgPort *port;
  412. X*
  413. X* Flag = 1L -- Raw mode
  414. X*      = 0L -- Cooked mode
  415. X* --------------------------------------------------------------------- *
  416. X    XDEF    SetConsoleType
  417. XSetConsoleType:
  418. X    movem.l    a2/a3/a5/a6,-(sp)
  419. X
  420. X    movea.l    a0,a3            ;Copy process pointer
  421. X    movea.l    a1,a5            ;Copy packet pointer
  422. X    lea    sp_Pkt(a5),a0        ;a0 = &packet->sp_Pkt
  423. X    move.l    a0,sp_Msg+LN_NAME(a5)    ;p->sp_Msg.mn_Node.ln_Name = &p->sp_Pkt
  424. X    lea    sp_Msg(a5),a0        ;a0 = &packet->sp_Msg
  425. X    move.l    a0,sp_Pkt+dp_Link(a5)    ;p->sp_Pkt.dp_Link = &p->sp_Msg
  426. X    move.l    a2,sp_Pkt+dp_Port(a5)    ;p->sp_Pkt.dp_Port = replyport
  427. X    move.l    #ACTION_SCREEN_MODE,sp_Pkt+dp_Type(a5)    ;Set function
  428. X
  429. X    tst.w    d0            ;On or Off?
  430. X     beq    1$
  431. X    move.l    #-1,sp_Pkt+dp_Arg1(a5)    ;RAW ON
  432. X    bra.s    2$
  433. X1$
  434. X    clr.l    sp_Pkt+dp_Arg1(a5)    ;RAW OFF
  435. X2$
  436. X    movea.l    a3,a0
  437. X    movea.l    a5,a1
  438. X    SYS    PutMsg,4        ;PutMsg(proc, packet)
  439. X
  440. X    movea.l    a2,a0
  441. X    SYS    WaitPort        ;WaitPort(port)
  442. X    movea.l    a2,a0
  443. X    SYS    GetMsg            ;(void)GetMsg(port)
  444. X
  445. X    movem.l    (sp)+,a2/a3/a5/a6
  446. X    rts
  447. X
  448. X* ------------------------------------------------------------------------- *
  449. X* struct MsgPort *CreatePort(name, pri) (a0/d0)
  450. X* ------------------------------------------------------------------------- *
  451. X    XDEF    CreatePort
  452. XCreatePort:
  453. X    movem.l    d5/d7/a2/a5/a6,-(sp)
  454. X
  455. X    move.l    a0,a5            ;Save Name
  456. X    move.l    d0,d5            ;Save Pri
  457. X
  458. X* Allocate a free signal, crap out if we can't
  459. X    moveq    #-1,d0
  460. X    SYS    AllocSignal,4
  461. X    cmp.l    #-1,d0            ;Did we get a signal?
  462. X     bne.s    cpgotsig        ;Yep
  463. X    moveq    #0,d0            ;Otherwise return NULL
  464. X    bra    cpdone
  465. X
  466. Xcpgotsig:
  467. X    move.l    d0,d7            ;Save our signal
  468. X
  469. X* Allocate memory for MsgPort
  470. X    moveq    #MP_SIZE,d0        ;Size of MsgPort
  471. X    jsr    @myalloc        ;Allocate it
  472. X    tst.l    d0            ;Did we get it?
  473. X     bne.s    cpgotport        ;Yep
  474. X
  475. X    move.l    d7,d0            ;Otherwise crap out, free signal
  476. X    SYS    FreeSignal
  477. X    moveq    #0,d0            ;Return NULL
  478. X    bra    cpdone
  479. X
  480. Xcpgotport:
  481. X    move.l    d0,a2            ;This is our new port!
  482. X    move.l    a5,LN_NAME(a2)        ;port->mp_Node.ln_Name = name
  483. X    move.b    d5,LN_PRI(a2)        ;port->mp_Node.ln_Pri = priority
  484. X    move.b    #NT_MSGPORT,LN_TYPE(a2) ;port->mp_Node.ln_Type = NT_MSGPORT
  485. X    move.b    #PA_SIGNAL,MP_FLAGS(a2) ;port->mp_Flags = PA_SIGNAL
  486. X    move.b    d7,MP_SIGBIT(a2)    ;port->mp_SIGBIT = sigBit
  487. X    suba.l    a1,a1
  488. X    SYS    FindTask
  489. X    move.l    d0,MP_SIGTASK(a2)    ;port->mp_SIGTASK = FindTask(0L)
  490. X    
  491. X    cmpa.l    #0,a5            ;Is this a new name?
  492. X    beq.s    cpnoname        ;Nope, add it to the msg list
  493. X
  494. X    movea.l    a2,a1
  495. X    SYS    AddPort            ;Otherwise add this port
  496. X    move.l    a2,d0            ;Return port pointer
  497. X    bra.s    cpdone
  498. X
  499. Xcpnoname:
  500. X* Initialized New List head
  501. X    lea    MP_MSGLIST(a2),a0     ;a0 = &port->mp_MsgList
  502. X    move.l    a0,(a0)            ;list->lh_Head = list
  503. X    addq.l    #4,(a0)            ;list->lh_Head += 4L
  504. X    clr.l    4(a0)            ;list->lh_Tail = 0L
  505. X    move.l    a0,8(a0)        ;list->lh_TailPred = list
  506. X    move.l    a2,d0            ;Return port pointer
  507. X
  508. Xcpdone:
  509. X    movem.l    (sp)+,d5/d7/a2/a5/a6
  510. X    rts
  511. X
  512. X* ------------------------------------------------------------------------- *
  513. X* DeletePort(port)(d0)
  514. X* ------------------------------------------------------------------------- *
  515. X    XDEF    DeletePort
  516. XDeletePort:
  517. X    movem.l    a5/a6,-(sp)
  518. X
  519. X    move.l    d0,a5
  520. X    movea.l    $4,a6
  521. X    tst.l    LN_NAME(a5)        ;Is there a name?
  522. X    beq.s    dpnoname
  523. X    
  524. X    move.l    d0,a1
  525. X    SYS    RemPort            ;RemPort(port)
  526. X    
  527. Xdpnoname:
  528. X    move.b    #$ff,LN_TYPE(a5)     ;port->mp_Node.ln_Type = 0xff
  529. X    move.l    #-1,MP_MSGLIST(a5)     ;port->mp_MsgList.lh_Head = -1L
  530. X
  531. X    moveq    #0,d0
  532. X    move.b    MP_SIGBIT(a5),d0    ;d0 = port->mp_SigBit
  533. X    SYS    FreeSignal        ;FreeSignal(d0)
  534. X
  535. X    movea.l    a5,a0
  536. X    jsr    @myfree            ;FreeBlock(port)
  537. X
  538. X    movem.l    (sp)+,a5/a6
  539. X    rts
  540. X
  541. X* ------------------------------------------------------------------------
  542. X* FibFileDate(fib_date, datestr, timestr)
  543. X*               a0      a1       8(a5)
  544. X*   struct DateStamp *fib_date;
  545. X*   char *datestr, *timestr;
  546. X*   Calculate date based on DateStamp structure and return a pointer
  547. X* to the formatted date string.
  548. X* ------------------------------------------------------------------------
  549. X    XDEF    @FibFileDate
  550. X@FibFileDate:
  551. X    link    a5,#0
  552. X    movem.l    d3-d7/a2-a3/a6,-(sp)
  553. X
  554. X    movea.l    a1,a3            ;a3 = datestr, 8(a5) = timestr
  555. X    movea.l    a0,a1            ;Grab datestamp pointer
  556. X    moveq    #78,d7            ;Initial year = 1978
  557. X
  558. X    move.l    (a1),d5            ;days = fib_date->ds_Days
  559. X     blt    ffdbaddate        ;Hey! you can't be negative! Invalid date...
  560. X
  561. X* Determine what year it is
  562. X    divu    #1461,d5
  563. X    move.l    d5,d0            ;Stash it
  564. X    ext.l    d5
  565. X    lsl.l    #2,d5
  566. X    add.l    d5,d7            ;year += (days / 1461) * 4
  567. X
  568. X* Count how many months into that year
  569. Xffdgetmo:
  570. X    swap    d0            ;days %= 1461
  571. X    move.w    d0,d5
  572. X
  573. X1$    tst.w    d5            ;Out of days yet?
  574. X     beq.s    3$            ;Yep, done here
  575. X
  576. X    move.w    #365,d6            ;Else month_days = 365
  577. X    move.w    d7,d0            ;Grab year
  578. X    andi.w    #3,d0            ;if (year & 3) == 0 Leap year?
  579. X     bne.s    2$            ;Nope
  580. X    addq.w    #1,d6            ;Otherwise bump month_days
  581. X
  582. X2$    cmp.w    d6,d5            ;is day < month_days?
  583. X     blt.s    3$            ;yep, done here
  584. X    sub.w    d6,d5            ;otherwise day -= month_days
  585. X
  586. X    addq.l    #1,d7            ; year++
  587. X    bra    1$
  588. X3$
  589. X
  590. X* Count how many days into that month of that year
  591. Xffdgetday:
  592. X;for (i = 0, day++; i < 12; i++)
  593. X    moveq    #0,d4            ;current month = 0
  594. X    moveq    #0,d6            ;Zap hinybs
  595. X    addq.w    #1,d5
  596. X    lea    dayspermonth(a4),a0
  597. X
  598. X1$
  599. X    move.b    0(a0,d4.w),d6        ;month_days = dayspermonth[i]
  600. X
  601. X    cmpi.w    #1,d4            ;if (i == 1 && (year & 3) == 0)
  602. X     bne.s    2$
  603. X    move.w    d7,d0
  604. X    andi.w    #3,d0
  605. X     bne.s    2$
  606. X    addq.w    #1,d6            ;month_days++
  607. X
  608. X2$    cmp.w    d6,d5            ;if (day <= month_days)
  609. X     ble.s    4$            ;Break out, found the right month
  610. X
  611. X    sub.w    d6,d5            ;Else, day -= month_days
  612. X
  613. X    addq.w    #1,d4            ;i++
  614. X3$    cmpi.w    #12,d4            ;Done all months yet?
  615. X     blt    1$            ;Nope
  616. X
  617. X4$
  618. Xffdprint:
  619. X1$    cmpi.l    #99,d7            ;while (year >= 100)
  620. X     ble.s    2$
  621. X    subi.l    #100,d7            ;year -= 100
  622. X    bra    1$
  623. X2$
  624. X;asprintf(datestr, "%02d-%02d-%02d %02d:%02d:%02d", i + 1, day, year, hour, min, sec)
  625. X    move.l    8(a1),d0        ;sec = fib_date->ds_Tick / 50;
  626. X    divu    #50,d0
  627. X    ext.l    d0
  628. X    move.l    d0,-(sp)        ;Push secs
  629. X    move.l    4(a1),d0        ;min = fib_date->ds_Minute
  630. X    move.l    d0,d1            ;Clone it
  631. X    divu    #60,d0
  632. X    moveq    #0,d3
  633. X    move.w    d0,d3            ;hour = min / 60
  634. X    mulu    #60,d0
  635. X    sub.w    d0,d1            ;min -= hour * 60
  636. X    move.l    d1,-(sp)        ;Push mins
  637. X    move.l    d3,-(sp)        ;Push hours
  638. X    pea    timepat(a4)        ;Push the format pattern
  639. X    move.l    8(a5),-(sp)        ;Push destination buffer, datestr
  640. X    jsr    asprintf
  641. X    lea    20(sp),sp
  642. X
  643. X    move.l    d5,-(sp)        ;Push day
  644. X    addq.w    #1,d4            ;Push month (offset by 1!)
  645. X    move.l    d4,-(sp)
  646. X    move.l    d7,-(sp)        ;Push year
  647. X    pea    datepat(a4)        ;Push the format pattern
  648. X    move.l    a3,-(sp)        ;Push destination buffer
  649. X    jsr    asprintf    
  650. X    lea    20(sp),sp
  651. X
  652. Xffddone:
  653. X    movem.l    (sp)+,d3-d7/a2-a3/a6
  654. X    unlk    a5
  655. X    rts
  656. X
  657. Xffdbaddate:
  658. X    lea    badtimestr(a4),a1    ;stpcpy (timestr, "00:00:00");
  659. X    movea.l    8(a5),a0
  660. X    jsr    @stpcpy
  661. X    lea    baddatestr(a4),a1    ;stpcpy (datestr, "00-00-00");
  662. X    movea.l    a3,a0
  663. X    jsr    @stpcpy
  664. X    bra    ffddone
  665. X
  666. X*----------------------------------------------------------------------
  667. X* LONG iswild(name)
  668. X*   char *name;
  669. X*          a0
  670. X* Search a string for wild characters, return 1 if found
  671. X*----------------------------------------------------------------------
  672. X    XDEF    @iswild
  673. X@iswild:
  674. X    moveq    #0,d0            ;Clear out our character register
  675. Xischk1:
  676. X    move.b    (a0)+,d0        ;Grab a char
  677. X     beq.s    iwdone            ;Might be end of string?
  678. X    cmpi.b    #'*',d0            ;Is it *?
  679. X     beq.s    iswdone            ;yep, is wild
  680. X    cmpi.b    #'?',d0            ;Is it a qmark
  681. X     bne.s    ischk1            ;Nope, check next character
  682. X
  683. Xiswdone:
  684. X    moveq    #1,d0
  685. Xiwdone:
  686. X    rts
  687. X
  688. X* ------------------------------------------------------------------------
  689. X; Compare a wild card name with a normal name
  690. X; LONG wildmatch (name, wild)
  691. X;   char *name, *wild;
  692. X;          a0     a1
  693. X* ------------------------------------------------------------------------
  694. X    XDEF    @wildmatch
  695. X@wildmatch:
  696. X    link    a5,#-64
  697. X    movem.l    d3/a2-a3,-(sp)
  698. X
  699. X    movea.l    a0,a2            ;Grab name
  700. X    movea.l    a1,a3            ;Grab pattern
  701. X    lea    -64(a5),a0        ;back[0][0]
  702. X    lea    -60(a5),a1        ;back[0][1]
  703. X
  704. X    moveq    #0,d3            ;bi = 0
  705. X
  706. Xwmloop1:
  707. X    tst.b    (a2)            ;End of name?
  708. X     bne.s    wmnoteon
  709. X    tst.b    (a3)            ;End of pattern?
  710. X     beq    wmmatched        ;Yep, we matched
  711. X
  712. Xwmnoteon:
  713. X    cmpi.b    #'*',(a3)        ;Is it a splat?
  714. X     bne.s    wmnotstar        ;Nope, maybe '?'
  715. X
  716. X    cmpi.w    #64,d3            ;Have we hit max expression depth?
  717. X     beq    wmnomatch        ;Yep, ran out of room in recursion table
  718. X
  719. X;back[bi][0] = w
  720. X    move.l    a3,0(a0,d3.w)        ;Stash pointer to this '*' in table
  721. X
  722. X;back[bi][1] = n
  723. X    move.l    a2,0(a1,d3.w)
  724. X
  725. X    addq.w    #8,d3            ;++bi
  726. X    addq.w    #1,a3            ;++w
  727. X    bra.s    wmloop1            ;Check next
  728. X
  729. Xwmgoback:
  730. X    subq.w    #8,d3            ;--bi
  731. X    move.l    a0,d0
  732. Xwmback1:
  733. X    tst.w    d3            ;while (bi >= 0 && *back[bi][1] == '\x0')
  734. X     blt.s    wmbacked
  735. X    movea.l    0(a1,d3.l),a0
  736. X    tst.b    (a0)
  737. X     bne.s    wmbacked
  738. X
  739. X    subq.w    #8,d3            ;--bi
  740. X    bra.s    wmback1
  741. X
  742. Xwmbacked:
  743. X    tst.w    d3            ;if (bi < 0)
  744. X     blt.s    wmnomatch        ;return (0)
  745. X
  746. X    movea.l    d0,a0
  747. X    movea.l    0(a0,d3.w),a3        ;w = back[bi][0] + 1
  748. X    addq.w    #1,a3    
  749. X
  750. X    addq.l    #1,0(a1,d3.w)
  751. X    movea.l    0(a1,d3.l),a2        ;n = ++back[bi][1]
  752. X
  753. X    addq.w    #8,d3            ;++bi
  754. X    bra.s    wmloop1
  755. X
  756. Xwmnotstar:
  757. X    cmpi.b    #'?',(a3)        ;Is it '?'
  758. X     bne.s    wmnotqmark
  759. X
  760. X    tst.b    (a2)            ;Reached end of string?
  761. X     bne.s    wmincpoint        ;Nope, move on to next char
  762. X
  763. X    tst.w    d3            ;Are we at top level of expression?
  764. X     beq.s    wmnomatch        ;Yep, expression didn't match
  765. X    bra.s    wmgoback        ;Otherwise pop a level and try to match
  766. X
  767. Xwmnotqmark:
  768. X    move.b    (a2),d0            ;Grab a char from bstr
  769. X    cmpi.b    #$40,d0            ;less than @ character?
  770. X     bls.s    1$            ;Yep
  771. X    cmpi.b    #$5a,d0            ;Greater than Z?
  772. X     bhi.s    1$            ;Yep
  773. X    addi.b    #$20,d0
  774. X1$
  775. X    move.b    (a3),d1            ;Grab a char from bstr
  776. X    cmpi.b    #$40,d1            ;less than @ character?
  777. X     bls.s    2$            ;Yep
  778. X    cmpi.b    #$5a,d1            ;Greater than Z?
  779. X     bhi.s    2$            ;Yep
  780. X    addi.b    #$20,d1
  781. X2$
  782. X    cmp.b    d0,d1            ;*n = *w?
  783. X     beq.s    wmincpoint        ;Yep, move on past
  784. X
  785. X    tst.w    d3            ;Are we at top expression level?
  786. X     beq.s    wmnomatch        ;Yep, they didn't match
  787. X    bra.s    wmgoback        ;Nope, process next part
  788. X
  789. Xwmincpoint:
  790. X    tst.b    (a2)            ;Done with name?
  791. X     beq.s    wmnamend        ;Yep
  792. X    addq.w    #1,a2            ;Otherwise increment name pointer
  793. X
  794. Xwmnamend:
  795. X    tst.b    (a3)            ;End of pattern?
  796. X     beq.s    wmmatched        ;Yep, we matched
  797. X    addq.w    #1,a3            ;Otherwise inc wild pointer, match next char
  798. X    bra    wmloop1
  799. X
  800. Xwmmatched:
  801. X    moveq    #1,d0
  802. X    bra.s    wmdone
  803. X
  804. Xwmnomatch:
  805. X    moveq    #0,d0
  806. X
  807. Xwmdone:
  808. X    movem.l    (sp)+,d3/a2-a3
  809. X    unlk    a5
  810. X    rts
  811. X
  812. X* --------------------------------------------------------------------- *
  813. X* BOOL CompFibs (keytype, a,   b)
  814. X*            d0   a0   a1
  815. X*   LONG keytype;
  816. X*   struct FileInfoBlock *a, *b;
  817. X*
  818. X* Used by SortFibs to determine precedence of Fibs.
  819. X* keytype is one of 0, 1, or 2:
  820. X*   0=alpha, 1=size, 2=date
  821. X* --------------------------------------------------------------------- *
  822. X    XDEF    @CompFibs
  823. X@CompFibs:
  824. X    movem.l    d2-d3/a2,-(sp)
  825. X
  826. X    move.l    d0,d2            ;Stash keytype
  827. X
  828. X* Prioritize Dirs/Files?
  829. X    move.l    LSFlags(a4),d3        ;Grab flags
  830. X
  831. X    btst.l    #17,d3            ;LSFlags & MIXFILEDIRS?
  832. X     bne.s    cftstsort        ;Yep, don't bother comparing EntryTypes
  833. X
  834. X    move.l    fib_DirEntryType(a0),d0
  835. X    cmp.l    fib_DirEntryType(a1),d0
  836. X     blt.s    1$            ;a0 is < a1, (dir < file)
  837. X     beq.s    cftstsort        ;a0 is == a1, try next test
  838. X
  839. X    moveq    #0,d0            ;a0 is > a1, (file > dir)
  840. X    bra.s    2$
  841. X1$
  842. X    moveq    #1,d0            ;greater than, (dir < file)
  843. X
  844. X2$    btst.l    #16,d3            ;LSFlags & FILESFIRST?
  845. X     beq    cfexit0            ;Nope, default Dirs first
  846. X    bchg.l    #0,d0            ;Else d0 ^= 1, reverse sense
  847. X    bra    cfexit0
  848. X    
  849. X* Both entries are the same type, now see about sorting them
  850. Xcftstsort:
  851. X    btst.l    #6,d3            ;LSFlags & NOSORTFLAG set?
  852. X     bne    cffalse            ;Yep, always AddTail to list
  853. X    
  854. X* Switch keytype
  855. X    tst.w    d2            ;Alphabetize?
  856. X     bne.s    cfnalpha        ;Nope
  857. X
  858. X* Compare lexigraphically, ignoring case differences
  859. Xcfalpha:
  860. X    lea    fib_FileName(a0),a0    ;a = &Fipb->fib_FileName
  861. X    lea    fib_FileName(a1),a1    ;b = &Fipb->fib_FileName
  862. X
  863. X;  for(; *a && tolower(*a) == tolower(*b); a++, b++);
  864. Xlccstart:
  865. X    tst.b    (a0)            ;Is there a char here at source?
  866. X     beq.s    lcceostr        ;Nope, fell off the end
  867. X
  868. X    move.b    (a1)+,d1        ;Grab a char from bstr
  869. X    cmpi.b    #$40,d1            ;less than @ character?
  870. X     bls.s    1$            ;Yep
  871. X    cmpi.b    #$5a,d1            ;Greater than Z?
  872. X     bhi.s    1$            ;Yep
  873. X    addi.b    #$20,d1
  874. X1$
  875. X    move.b    (a0)+,d0        ;Grab a char from astr
  876. X    cmpi.b    #$40,d0            ;less than @ character?
  877. X     bls.s    2$            ;Yep
  878. X    cmpi.b    #$5a,d0            ;Greater than Z?
  879. X     bhi.s    2$            ;Yep
  880. X    addi.b    #$20,d0
  881. X2$
  882. X    cmp.b    d0,d1            ;are they the same?
  883. X     beq    lccstart        ;Yep, compare next pair of chars
  884. X
  885. Xlcceostr:
  886. X    sub.b    d1,d0            ;return(tolower(*astr) - tolower(*bstr))
  887. X     bgt.s    cftrue            ; > 0?, return TRUE
  888. X    bra.s    cffalse            ;Else return FALSE
  889. X
  890. Xcfnalpha:
  891. X    subq.w    #1,d2            ;Size?
  892. X     bne.s    cfnsize            ;Nope
  893. X
  894. X* Compare fib_Sizes
  895. X    move.l    fib_Size(a0),d0        ;d0 = afib->fib_Size
  896. X    cmp.l    fib_Size(a1),d0        ;b->fib_Size > a->fib_Size?
  897. X     bgt.s    cftrue            ;Yep, return TRUE
  898. X     blt.s    cffalse            ;<, return FALSE
  899. X     bra    cfalpha            ;Else it's a tie, alphabetize
  900. X
  901. Xcfnsize:
  902. X* Compare fib_DateStamps
  903. X    lea    fib_DateStamp(a0),a0    ;a = &afib->fib_DateStamp
  904. X    lea    fib_DateStamp(a1),a1    ;b = &bfib->fib_DateStamp
  905. X    jsr    @CompareDateStamps
  906. X    tst.l    d0
  907. X     beq    cfalpha            ;its the same date?, alphabetize
  908. X     blt.s    cffalse
  909. Xcftrue:
  910. X    moveq    #1,d0
  911. X    bra.s    cfexit
  912. Xcffalse:
  913. X    moveq    #0,d0
  914. Xcfexit:
  915. X    btst.l    #9,d3            ;LSFlags & REVFLAG?
  916. X     beq.s    1$            ;Nope
  917. X    bchg.l    #0,d0            ;Else invert boolean result
  918. X1$
  919. Xcfexit0:
  920. X    movem.l    (sp)+,d2-d3/a2
  921. X    rts
  922. X
  923. X* --------------------------------------------------------------------- *
  924. X* LONG CompareDateStamps(adate, bdate)
  925. X*  d0                     a0      a1
  926. X*   struct DateStamp *adate, *bdate;
  927. X* --------------------------------------------------------------------- *
  928. X    XDEF    @CompareDateStamps
  929. X@CompareDateStamps:
  930. X    move.l    ds_Days(a0),d0        ;d0 = adate->ds_Days
  931. X    sub.l    ds_Days(a1),d0        ;b->ds_Days > a->ds_Days?
  932. X     bne.s    1$            ;Return b->day - a->day
  933. X
  934. X;They are the same day, check min/tick
  935. X    move.l    ds_Minute(a0),d0
  936. X    sub.l    ds_Minute(a1),d0    ;d0 = amin - bmin
  937. X    muls    #3000,d0        ;     * 3000
  938. X    add.l    ds_Tick(a0),d0
  939. X    sub.l    ds_Tick(a1),d0        ;     + atick - btick
  940. X1$
  941. X    rts
  942. X
  943. X* --------------------------------------------------------------------- *
  944. X* VOID InsertFibNode(hfib, newfib)
  945. X*                     a0     a1
  946. X*   struct List *hfib;
  947. X*   struct FibEntry *newfib;
  948. X*
  949. X* Compare data in newfib->Fib with nodes in the list until we
  950. X* find the insertion point.
  951. X* --------------------------------------------------------------------- *
  952. X    XDEF    @InsertFibNode
  953. X@InsertFibNode:
  954. X    movem.l    d2/a2-a3/a5/a6,-(sp)
  955. X
  956. X    move.l    sortkey(a4),d2
  957. X    movea.l    a0,a3            ;a3 = hfib
  958. X    movea.l    a1,a2            ;a2 = newfib
  959. X
  960. X    movea.l    LH_HEAD(a3),a5        ;afib = hfib->lh_Head
  961. X
  962. X1$    tst.l    fe_Node+LN_SUCC(a5)    ;afib->fe_Node.mln_Succ != 0?
  963. X     beq.s    4$
  964. X
  965. X    movea.l    fe_Fib(a2),a1
  966. X    movea.l    fe_Fib(a5),a0
  967. X    move.l    d2,d0
  968. X    jsr    @CompFibs        ;CompFibs(sortkey, afib->Fib, newfib->Fib)
  969. X    tst.w    d0
  970. X     bne.s    4$
  971. X    movea.l    fe_Node+LN_SUCC(a5),a5    ;afib = afib->fe_Node.mln_Succ
  972. X    bra    1$
  973. X
  974. X4$    movea.l    a3,a0            ;a0 = List *
  975. X    movea.l    a2,a1            ;a1 = Node *
  976. X    movea.l    fe_Node+LN_PRED(a5),a2    ;a2 = Pred *
  977. X    SYS    Insert,4        ;Insert(hfib, newfib, afib->fe_Node.mln_Succ)
  978. X
  979. X    movem.l    (sp)+,d2/a2-a3/a5/a6
  980. X    rts
  981. X
  982. X* --------------------------------------------------------------------- *
  983. X* LONG FillFibEntry (headfib, fibp)
  984. X*               a0      a1          
  985. X*   struct List *headfib;
  986. X*   struct FileInfoBlock *fibp;
  987. X* --------------------------------------------------------------------- *
  988. X    XDEF    @FillFibEntry
  989. X@FillFibEntry:
  990. X    movem.l    a2-a3/a5/a6,-(sp)
  991. X    movea.l    a0,a2            ;a2 = head of list
  992. X    movea.l    a1,a3            ;a3 = fileinfoblock
  993. X
  994. X    jsr    @AllocFib        ;Allocate a new fib
  995. X    tst.l    d0            ;Got it?
  996. X     beq.s    3$            ;Nope, return 0
  997. X    movea.l    d0,a5            ;a5 = tfibp = AllocFib()
  998. X
  999. X    move.l    #fib_SIZEOF,d0
  1000. X    movea.l    fe_Fib(a5),a1
  1001. X    movea.l    a3,a0
  1002. X    SYS    CopyMem,4        ;CopyMem(fibp, tfibp->Fib, sizeof(struct fib))
  1003. X
  1004. X    movea.l    a5,a1
  1005. X    movea.l    a2,a0
  1006. X
  1007. X    jsr    @InsertFibNode        ;InsertFibNode(headfib, tfibp)
  1008. X
  1009. X    moveq    #1,d0            ;return(1)
  1010. X3$
  1011. X    movem.l    (sp)+,a2-a3/a5/a6
  1012. X    rts
  1013. X
  1014. X* --------------------------------------------------------------------- *
  1015. X    XDEF    @nullstub
  1016. X@nullstub:
  1017. X    moveq    #0,d0
  1018. X    rts
  1019. X
  1020. X* --------------------------------------------------------------------- *
  1021. X* LONG GetPathString (dest, src)
  1022. X*  d0                  a0    a1
  1023. X*   BYTE *dest, *src;
  1024. X* --------------------------------------------------------------------- *
  1025. X    XDEF    @GetPathString
  1026. X@GetPathString:
  1027. X    move.l    a2,-(sp)
  1028. X
  1029. X    moveq    #0,d0            ;Zero return dest length
  1030. X
  1031. X* Find end of src string
  1032. X    movea.l    a1,a2            ;Save src start address
  1033. X1$    tst.b    (a1)+            ;while (*src++ != 0)
  1034. X     bne    1$
  1035. X
  1036. X* Work backwards till we find a ':' or a '/'
  1037. X2$    move.b    -(a1),d1        ;c = *(--src)
  1038. X    cmpi.b    #':',d1            ;Hit a colon?
  1039. X     beq.s    4$            ;Yep, found our path end
  1040. X    cmpi.b    #'/',d1            ;Hit a slash?
  1041. X     bne.s    3$            ;Nope, try next char
  1042. X    cmpa.l    a2,a1            ;At first char?
  1043. X     beq.s    4$            ;Yep, leave the single slash
  1044. X    cmpi.b    #'/',-1(a1)        ;Next char back is also a '/'?
  1045. X     beq.s    4$            ;Yep, allow multiple slashes
  1046. X    subq.w    #1,a1            ;Else backup to previous char, eliminate '/'
  1047. X    bra.s    4$
  1048. X3$
  1049. X    cmpa.l    a2,a1            ;Back at start of src?
  1050. X     bhi    2$            ;Nope, try previous src char
  1051. X    bra.s    gpsdone            ;Else no dest, return
  1052. X4$
  1053. X* Copy path portion to dest
  1054. Xgpscpy:
  1055. X    cmpa.l    a2,a1            ;Past end address?
  1056. X     bcs.s    gpsdone            ;Yep, terminate
  1057. X    move.b    (a2)+,(a0)+        ;Copy a char from src to dest
  1058. X    addq.w    #1,d0            ;Bump dest length count
  1059. X    bra    gpscpy            ;Check end address
  1060. Xgpsdone:
  1061. X    clr.b    (a0)            ;Null terminate dest
  1062. X
  1063. X    movea.l    (sp)+,a2
  1064. X    rts
  1065. X
  1066. X* --------------------------------------------------------------------- *
  1067. X* LONG GetFileString (dest, src)
  1068. X*  d0                  a0    a1
  1069. X*   BYTE *dest, *src;
  1070. X* --------------------------------------------------------------------- *
  1071. X    XDEF    @GetFileString
  1072. X@GetFileString:
  1073. X    move.l    a2,-(sp)
  1074. X
  1075. X    moveq    #0,d0            ;Zero return dest length
  1076. X
  1077. X* Find end of src string
  1078. X    movea.l    a1,a2            ;Save src start address
  1079. X1$    tst.b    (a1)+            ;while (*src++ != 0)
  1080. X     bne    1$
  1081. X
  1082. X* Work backwards till we find a ':' or a '/'
  1083. X2$    move.b    -(a1),d1        ;c = *(--src)
  1084. X    cmpi.b    #':',d1            ;Hit a colon?
  1085. X     beq.s    4$            ;Yep, found our path end
  1086. X    cmpi.b    #'/',d1            ;Hit a slash?
  1087. X     beq.s    4$            ;Nope, try next char
  1088. X3$
  1089. X    cmpa.l    a2,a1            ;Back at start of src?
  1090. X     bhi    2$            ;Nope, try previous src char
  1091. X    bra.s    gfscpy            ;Else no path, entire src is filename
  1092. X4$
  1093. X    addq.w    #1,a1            ;Move past ':' or '/'
  1094. X
  1095. X* Copy name portion to dest
  1096. Xgfscpy:
  1097. X    move.b    (a1)+,(a0)+        ;Copy a char from src to dest
  1098. X     beq.s    2$
  1099. X    addq.w    #1,d0            ;Bump dest length count
  1100. X    bra    gfscpy            ;Check end address
  1101. X2$
  1102. X    movea.l    (sp)+,a2
  1103. X    rts
  1104. X
  1105. X* ------------------------------------------------------------------------- *
  1106. X* BYTE *astrncpy(dst, src, len)
  1107. X* d0/a0          a0   a1    d0
  1108. X* Takes text in a1, copies d0 bytes to text in a0.
  1109. X* a0 returns pointing to null at end of final text.
  1110. X* Dest text is always null terminated.
  1111. X* ------------------------------------------------------------------------- *
  1112. X    XDEF    @astrncpy
  1113. X@astrncpy:
  1114. X1$    subq.l    #1,d0            ;Dec count
  1115. X     blt.s    2$            ;Done!
  1116. X
  1117. X    move.b    (a1)+,(a0)+        ;Copy a byte
  1118. X     bne    1$            ;Do until end of src or cnt < 0
  1119. X2$
  1120. X    clr.b    (a0)            ;Null terminate dest
  1121. X    move.l    a0,d0            ;Return in d0 also
  1122. X    rts
  1123. X
  1124. X* ------------------------------------------------------------------------- *
  1125. X* VOID amovmem(src, dst, len)
  1126. X*              a0    a1   d0
  1127. X* Takes text in a0, copies d0 bytes to text in a1. Correctly handles
  1128. X* overlapping memory.
  1129. X* ------------------------------------------------------------------------- *
  1130. X    XDEF    amovmem
  1131. Xamovmem:
  1132. X    cmpa.l    a0,a1            ;Low to high or high to low?
  1133. X     bcs.s    2$            ;High to low, copy forward
  1134. X    adda.w    d0,a0            ;Else start at end, copy backward
  1135. X    adda.w    d0,a1
  1136. X
  1137. X1$    move.b    -(a0),-(a1)
  1138. X    subq.w    #1,d0
  1139. X     bgt    1$
  1140. X    bra.s    amdone
  1141. X
  1142. X2$    move.b    (a0)+,(a1)+
  1143. X    subq.w    #1,d0
  1144. X     bgt    2$
  1145. Xamdone:
  1146. X    rts
  1147. X
  1148. X* --------------------------------------------------------------------- *
  1149. X* BYTE *aindex(BYTE *, BYTE);
  1150. X*  d0           a0      d0
  1151. X* --------------------------------------------------------------------- *
  1152. X    XDEF    @aindex
  1153. X@aindex:
  1154. X1$    cmp.b    (a0),d0
  1155. X     beq.s    aifound
  1156. X    tst.b    (a0)+
  1157. X     beq.s    ainomatch
  1158. X    bra    1$
  1159. X
  1160. Xainomatch:
  1161. X    moveq    #0,d0
  1162. X    rts
  1163. X
  1164. Xaifound:
  1165. X    move.l    a0,d0
  1166. X    rts
  1167. X
  1168. X* --------------------------------------------------------------------- *
  1169. X* LONG MakePathString(lock, dest)
  1170. X*                      a0     a1
  1171. X*   struct FileLock *lock;
  1172. X*   BYTE *dest;
  1173. X*
  1174. X* DESCRIPTION:
  1175. X*   Given text and a filelock, construct entire pathname and
  1176. X* return in dest.
  1177. X* --------------------------------------------------------------------- *
  1178. X    XDEF    @MakePathString
  1179. X@MakePathString:
  1180. X    movem.l    d2-d5/d7/a2-a3/a6,-(sp)
  1181. X
  1182. X* Grab pointer to lock and dest text to fill
  1183. X    move.l    a0,d3            ;d3 = lock
  1184. X    movea.l    a1,a2            ;a2 = dest
  1185. X    clr.b    (a2)            ;NULL terminate dest
  1186. X    moveq    #0,d5            ;LockFlag = 0
  1187. X
  1188. X* Allocate a FileInfoBlock for local use
  1189. X    move.l    #fib_SIZEOF,d0
  1190. X    jsr    @myalloc
  1191. X    move.l    d0,d7            ;d7 = *fib
  1192. X     beq    mpsfailed        ;Whoops no mem? return!
  1193. X
  1194. X    movea.l    DOSBase(a4),a6        ;DOSBase calls from here on
  1195. X
  1196. X* while (lock != 0)
  1197. X1$
  1198. X    tst.l    d3            ;Got a lock?
  1199. X     beq.s    mpsokay            ;Nope, must be at root
  1200. X
  1201. X* Examine the current lock
  1202. X    move.l    d3,d1
  1203. X    move.l    d7,d2
  1204. X    SYS    Examine            ;Examine(lock, fib)
  1205. X    tst.l    d0            ;Okay?
  1206. X     beq.s    mpsfailed        ;Nope, some sort of dos failure?
  1207. X
  1208. X    movea.l    d7,a1
  1209. X    cmpi.b    #' ',fib_FileName(a1)    ;if (fib->fib_FileName[0] >= ' ')
  1210. X     bcs.s    3$            ;Nope, don't bother inserting?
  1211. X
  1212. X    tst.b    (a2)            ;if (dest[0] != 0)
  1213. X     beq.s    2$
  1214. X    lea    SlashStr(a4),a1
  1215. X    movea.l    a2,a0
  1216. X    jsr    @InsertPathString    ;InsertPathString(dest, "/");
  1217. X2$
  1218. X    movea.l    d7,a1
  1219. X    lea    fib_FileName(a1),a1
  1220. X    movea.l    a2,a0
  1221. X    jsr    @InsertPathString    ;InsertPathString(dest, fib->fib_FileName)
  1222. X3$
  1223. X* Okay, move up one directory
  1224. X    move.l    d3,d4            ;oldlock = lock
  1225. X
  1226. X    move.l    d3,d1
  1227. X    SYS    ParentDir
  1228. X    move.l    d0,d3            ;lock = ParentDir(lock)
  1229. X
  1230. X    tst.w    d5            ;LockFlag set?
  1231. X     bne.s    4$            ;Yep, unlock
  1232. X    moveq    #1,d5            ;Else LockFlag = 1, unlock next time
  1233. X     bra    1$            ;Next directory up
  1234. X4$
  1235. X    move.l    d4,d1
  1236. X    SYS    UnLock            ;UnLock(oldlock)
  1237. X    bra    1$            ;Examine
  1238. X
  1239. Xmpsokay:
  1240. X* See if root was RAM:, special case
  1241. X    movea.l    d7,a1            ;a1 = fib
  1242. X    cmpi.b    #' ',fib_FileName(a1)    ;if (fib->fib_FileName[0] >= ' ')
  1243. X     bcc.s    1$            ;Yep, not 1.1/1.2 RAM:
  1244. X    lea    RamNameStr(a4),a1    ;Else...
  1245. X    movea.l    a2,a0
  1246. X    jsr    @InsertPathString    ;InsertPathString(dest, "RAM:")
  1247. X    bra.s    mpsdone
  1248. X1$
  1249. X* Find last slash we tacked on, change to a colon, or, add a colon
  1250. X    moveq    #'/',d0
  1251. X    movea.l    a2,a0
  1252. X    jsr    @aindex            ;d0 = strchr(dest, '/')
  1253. X    tst.l    d0            ;Do we have a slash?
  1254. X     beq.s    2$            ;Nope, at root....
  1255. X    movea.l    d0,a0
  1256. X    move.b    #':',(a0)        ;Else change first '/' to a ':'
  1257. X    bra.s    mpsdone
  1258. X
  1259. X* No slash, must be locked at the root.  Append a colon to the dest.
  1260. X2$
  1261. X    lea    ColonStr(a4),a1    
  1262. X    movea.l    a2,a0
  1263. X    jsr    @strcat            ;strcat (dest, ":")
  1264. X    bra.s    mpsdone
  1265. X
  1266. X* Come here if an error occured, return empty text to caller
  1267. Xmpsfailed:
  1268. X    clr.b    (a2)            ;dest[0] = (BYTE)0
  1269. X    moveq    #0,d3            ;return (0L)
  1270. X    bra.s    mpsdeall
  1271. X
  1272. X* Come here if everything is okay, deallocate FileInfoBlock
  1273. Xmpsdone:
  1274. X    moveq    #1,d3            ;return (1L)
  1275. X
  1276. Xmpsdeall:
  1277. X    tst.l    d7            ;Did we allocate a fib?
  1278. X     beq.s    mpsfinis        ;nope
  1279. X    movea.l    d7,a0            ;Else free the memory
  1280. X    jsr    @myfree
  1281. X
  1282. Xmpsfinis:
  1283. X    move.l    d3,d0            ;Put return value in d0
  1284. X    movem.l    (sp)+,d2-d5/d7/a2-a3/a6
  1285. X    rts
  1286. X
  1287. X* --------------------------------------------------------------------- *
  1288. X* VOID InsertPathString(dest, source)
  1289. X*                        a0     a1
  1290. X*   BYTE *dest, *source;
  1291. X*
  1292. X* DESCRIPTION:
  1293. X*   Insert source text into dest text.
  1294. X* Special case for source length == 0, source must be RAM.
  1295. X* --------------------------------------------------------------------- *
  1296. X    XDEF    @InsertPathString
  1297. X@InsertPathString:
  1298. X    movem.l    d7/a2-a3,-(sp)
  1299. X
  1300. X    movea.l    a1,a3            ;a3 = source
  1301. X    move.l    a0,a2            ;a2 = dest
  1302. X
  1303. X    movea.l    a3,a0
  1304. X    jsr    @strlen
  1305. X    move.l    d0,d7            ;d7 = strlen(source)
  1306. X
  1307. X1$    movea.l    a2,a0
  1308. X    jsr    @strlen            ;d0 = strlen(dest)
  1309. X
  1310. X    addq.w    #1,d0            ;Bump the length to include zero byte at end
  1311. X    movea.l    a2,a1
  1312. X    adda.w    d7,a1            ;Push dest + slen
  1313. X    movea.l    a2,a0            ;Push dest
  1314. X    jsr    amovmem            ;amovmem(dest, dest + slen, strlen(dest) + 1)
  1315. X
  1316. X    move.w    d7,d0
  1317. X    movea.l    a2,a1
  1318. X    movea.l    a3,a0
  1319. X    jsr    amovmem            ;amovmem(source, dest, slen)
  1320. X
  1321. X    movem.l    (sp)+,d7/a2-a3
  1322. X    rts
  1323. X
  1324. X* --------------------------------------------------------------------- *
  1325. X* VOID NoMemExit(VOID)
  1326. X* --------------------------------------------------------------------- *
  1327. X    XDEF    @NoMemExit
  1328. X@NoMemExit:
  1329. X    moveq    #103,d1
  1330. X    moveq    #20,d0
  1331. X    lea    NoRAMMsg(a4),a0
  1332. X    jsr    @CleanUp
  1333. X    rts
  1334. X
  1335. X* --------------------------------------------------------------------- *
  1336. X* VOID NoFileExit(name)
  1337. X*                  a0
  1338. X* BYTE *name;
  1339. X* --------------------------------------------------------------------- *
  1340. X    XDEF    @NoFileExit
  1341. X@NoFileExit:
  1342. X    movem.l    d2-d4/a6,-(sp)
  1343. X
  1344. X    move.l    a0,d2            ;Save name
  1345. X    SYS    IoErr,DOSBase(a4)    ;Get IoError status
  1346. X    move.l    d0,d3            ;Save it
  1347. X
  1348. X    move.l    #300,d0
  1349. X    jsr    @myalloc
  1350. X    move.l    d0,d4            ;d3 = myalloc( 300 )
  1351. X     bne.s    1$            ;Got it!
  1352. X    jsr    @NoMemExit        ;else exit with No Ram message
  1353. X    bra.s    2$
  1354. X1$
  1355. X    move.l    d2,-(sp)
  1356. X    pea    NoFindFmtStr(a4)
  1357. X    move.l    d4,-(sp)
  1358. X    jsr    asprintf        ;asprintf(tstr, NoFindFmtStr, name)
  1359. X    lea    12(sp),sp
  1360. X
  1361. X    move.l    d3,d1
  1362. X    moveq    #20,d0
  1363. X    movea.l    d4,a0
  1364. X    jsr    @CleanUp        ;CleanUp(tstr, 20L, IoErr())
  1365. X                    ;         a0   d0     d1
  1366. X    move.l    d4,a0
  1367. X    jsr    @myfree            ;free (tstr)
  1368. X2$
  1369. X    movem.l    (sp)+,d2-d4/a6
  1370. X    rts
  1371. X
  1372. X* --------------------------------------------------------------------- *
  1373. X    END
  1374. X* --------------------------------------------------------------------- *
  1375. END_OF_FILE
  1376. if test 33907 -ne `wc -c <'src/lssup.a'`; then
  1377.     echo shar: \"'src/lssup.a'\" unpacked with wrong size!
  1378. fi
  1379. # end of 'src/lssup.a'
  1380. fi
  1381. echo shar: End of archive 2 \(of 3\).
  1382. cp /dev/null ark2isdone
  1383. MISSING=""
  1384. for I in 1 2 3 ; do
  1385.     if test ! -f ark${I}isdone ; then
  1386.     MISSING="${MISSING} ${I}"
  1387.     fi
  1388. done
  1389. if test "${MISSING}" = "" ; then
  1390.     echo You have unpacked all 3 archives.
  1391.     rm -f ark[1-9]isdone
  1392. else
  1393.     echo You still need to unpack the following archives:
  1394.     echo "        " ${MISSING}
  1395. fi
  1396. ##  End of shell archive.
  1397. exit 0
  1398. -- 
  1399. Mail submissions (sources or binaries) to <amiga@cs.odu.edu>.
  1400. Mail comments to the moderator at <amiga-request@cs.odu.edu>.
  1401. Post requests for sources, and general discussion to comp.sys.amiga.
  1402.